import 'dart:io';
import 'dart:ui';

import 'package:extended_image/extended_image.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:flutter_smart_heating/common/app.dart';
import 'package:flutter_smart_heating/ui/ui.dart';
import 'package:get/get.dart';
import 'package:image_editor/image_editor.dart';
import 'package:path_provider/path_provider.dart';

class UiCrop extends StatefulWidget {
  const UiCrop({
    super.key,
    required this.file,
    this.onSaving,
    this.cropAspectRatio,
  });
  final File file;
  final Future Function(File file)? onSaving;
  final double? cropAspectRatio;

  static Future pick(
    BuildContext context, {
    Future Function(File file)? onSaving,
    double? cropAspectRatio,
  }) async {
    FilePickerResult? result =
        await FilePicker.platform.pickFiles(type: FileType.image);
    if (result != null) {
      File file = File(result.files.first.path!);
      // ignore: use_build_context_synchronously
      return await App.pushRoute(
        context,
        UiCrop(
          cropAspectRatio: cropAspectRatio,
          file: file,
          onSaving: onSaving,
        ),
        fullscreenDialog: true,
      );
    }
    return null;
  }

  @override
  State<UiCrop> createState() => _UiCropState();
}

class _UiCropState extends State<UiCrop> {
  final GlobalKey<ExtendedImageEditorState> editorKey =
      GlobalKey<ExtendedImageEditorState>();
  bool uploading = false;

  cancel({bool result = false}) async {
    editorKey.currentState?.reset();
    await 0.05.delay();
    Get.back(result: result);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: ExtendedImage.file(
        widget.file,
        fit: BoxFit.contain,
        extendedImageEditorKey: editorKey,
        mode: ExtendedImageMode.editor,
        cacheRawData: true,
        initEditorConfigHandler: (state) {
          return EditorConfig(
            cornerColor: UiTheme.primary,
            lineColor: Colors.white70,
            editorMaskColorHandler: (context, pointerDown) {
              return Colors.black54;
            },
            hitTestSize: 20,
            cropAspectRatio:
                widget.cropAspectRatio ?? CropAspectRatios.ratio1_1,
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        backgroundColor: Colors.transparent,
        onPressed: () {
          editorKey.currentState?.rotate();
        },
        mini: true,
        child: const Icon(
          Icons.rotate_left,
          color: Colors.white,
        ),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.startFloat,
      bottomNavigationBar: IntrinsicHeight(
        child: Container(
          color: Colors.black,
          padding: const EdgeInsets.symmetric(horizontal: 10),
          child: Column(
            children: [
              const Divider(
                color: Colors.white24,
                height: 0,
              ),
              SafeArea(
                bottom: true,
                top: false,
                minimum: const EdgeInsets.only(bottom: 15),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    TextButton(
                      onPressed: cancel,
                      style: ButtonStyle(
                        overlayColor: Ui.createTextBtnBgColor(),
                      ),
                      child: Text(
                        'Cancel'.tr,
                        style: const TextStyle(color: Colors.white70),
                      ),
                    ),
                    TextButton(
                      onPressed: uploading
                          ? null
                          : () {
                              editorKey.currentState?.reset();
                            },
                      style:
                          TextButton.styleFrom(foregroundColor: Colors.white70),
                      child: Text('Restore'.tr),
                    ),
                    TextButton(
                      style: TextButton.styleFrom(
                          disabledForegroundColor:
                              UiTheme.primary.withOpacity(0.6)),
                      onPressed: uploading
                          ? null
                          : () async {
                              setState(() {
                                uploading = true;
                              });
                              File? file = await cropImageDataWithNativeLibrary(
                                state: editorKey.currentState!,
                              );
                              if (file == null) {
                                setState(() {
                                  uploading = false;
                                });
                                return Ui.toast('裁剪失败');
                              }
                              await widget.onSaving?.call(file);
                              clearMemoryImageCache();
                              cancel(result: true);
                            },
                      child: uploading
                          ? const SizedBox(
                              width: 20,
                              height: 20,
                              child: CircularProgressIndicator(
                                strokeWidth: 3,
                              ),
                            )
                          : Text('Save'.tr),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Future<File?> cropImageDataWithNativeLibrary({
  required ExtendedImageEditorState state,
  int minHeight = 500,
  int minWidth = 500,
}) async {
  Rect cropRect = state.getCropRect()!;
  if (state.widget.extendedImageState.imageProvider is ExtendedResizeImage) {
    final ImmutableBuffer buffer =
        await ImmutableBuffer.fromUint8List(state.rawImageData);
    final ImageDescriptor descriptor = await ImageDescriptor.encoded(buffer);

    final double widthRatio = descriptor.width / state.image!.width;
    final double heightRatio = descriptor.height / state.image!.height;
    cropRect = Rect.fromLTRB(
      cropRect.left * widthRatio,
      cropRect.top * heightRatio,
      cropRect.right * widthRatio,
      cropRect.bottom * heightRatio,
    );
  }

  final EditActionDetails action = state.editAction!;

  final int rotateAngle = action.rotateAngle.toInt();
  final bool flipHorizontal = action.flipY;
  final bool flipVertical = action.flipX;
  final Uint8List img = state.rawImageData;

  final ImageEditorOption option = ImageEditorOption();

  if (action.needCrop) {
    option.addOption(ClipOption.fromRect(cropRect));
  }

  if (action.needFlip) {
    option.addOption(
        FlipOption(horizontal: flipHorizontal, vertical: flipVertical));
  }

  if (action.hasRotateAngle) {
    option.addOption(RotateOption(rotateAngle));
  }

  final Uint8List? result = await ImageEditor.editImage(
    image: img,
    imageEditorOption: option,
  );
  if (result == null) {
    return null;
  }
  var bytes = await FlutterImageCompress.compressWithList(
    result,
    minHeight: minHeight,
    minWidth: minWidth,
    quality: 80,
    format: CompressFormat.jpeg,
  );

  var tempDir = await getTemporaryDirectory();
  File file =
      await File('${tempDir.path}/image_change_temp_avatar.jpg').create();
  file.writeAsBytesSync(bytes);
  return file;
}
